use warnings;
use strict;

use Log::Log4perl qw(:easy);
use POE qw(Component::Server::TCP Filter::Stream);
use JSON;
use Data::Dumper;

use Dogtanian;
use odch_handler;

Log::Log4perl->easy_init($DEBUG);

my $outgoing = {};

sub execute {
	my $client = shift;
	my $method = shift;
	my $args = shift;
	no strict 'refs';
	if (defined &{"odch_handler::$method"}) {
		local $::current_client = $client;
		"odch_handler::$method"->(@$args);
	}
}

POE::Component::Server::TCP->new(
	InlineStates => {
		handle_odch => sub {
			my ($heap, $function_call) = @_[HEAP, ARG0];
			my $function_name = $function_call->[0];
			my $function_args = $function_call->[1];

			DEBUG "about to call $function_name";
			execute($heap->{client}, $function_name, $function_args);
		}
	},
	Alias        => "bot_server",
	Port         => 9003,

	ClientConnected => sub {
		INFO "got connection from hub\n";
	},

	ClientInput  => sub {
		my ($data, $heap) = @_[ARG0, HEAP];
		my $message = decode_json($data);

		if ($message->{type} eq 'register_incoming') {
			$heap->{name} = $message->{name};
		}

		if ($message->{type} eq 'register_outgoing') {
			$heap->{name} = $message->{name};

			if (defined $outgoing->{$message->{name}}) {
				DEBUG "removing previous outgoing handle for $message->{name}";
				my $outgoing_client = $outgoing->{$message->{name}};
				$poe_kernel->post($outgoing_client => 'shutdown');
			}

			$outgoing->{$message->{name}} = $_[SESSION]->ID;
		}

		if ($message->{type} eq 'function') {
			my $outgoing_id = $outgoing->{$heap->{name}};
			$poe_kernel->call($outgoing_id => handle_odch => $message->{details});
		}
	}
);

Dogtanian::load('plugins');
POE::Kernel->run() or die "couldn't start poe: $@\n";

print "running";
